package com.sktlab.bizconfmobile.activity;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TimePicker;

import com.sktlab.bizconfmobile.R;
import com.sktlab.bizconfmobile.customview.SlipControlView;
import com.sktlab.bizconfmobile.customview.TextArrow;
import com.sktlab.bizconfmobile.model.Constant;
import com.sktlab.bizconfmobile.model.ContactItem;
import com.sktlab.bizconfmobile.model.Meeting;
import com.sktlab.bizconfmobile.model.Participant;
import com.sktlab.bizconfmobile.model.db.MeetingDBAdapter;
import com.sktlab.bizconfmobile.model.db.MeetingDbTable;
import com.sktlab.bizconfmobile.model.manager.MeetingManager;
import com.sktlab.bizconfmobile.model.manager.ContactManager;
import com.sktlab.bizconfmobile.util.CalendarUtil;
import com.sktlab.bizconfmobile.util.DateUtil;
import com.sktlab.bizconfmobile.util.StringUtil;
import com.sktlab.bizconfmobile.util.Util;

public class OrderConfActivity extends BaseActivity {

	public static final String TAG = "OrderConfActivity";

	public final int DIALOG_TYPE_DATE = 0;
	public final int DIALOG_TYPE_TIME = 1;

	public final int REQUEST_CODE_ACCESS_NUMBER = 1001;
	public final int REQUEST_CODE_REPEAT_PERIOD = 1002;

	public final int TIME_START = 0;
	public final int TIME_END = 1;

	// one hour gap time for start date and end date
	public final long GAP_TIME = 3600000L;
	// To specified the operate time is start time or end time
	public int mTimeType = -1;
	// repeat period of the meeting
	public int mRepeatType = RepeatSelectionActivity.PERIOD_NONE;

	private Activity mActivity;
	private LayoutInflater mInflater;

	private long mAccountId;

	private Date mDate = new Date();
	private Date mStartDate = new Date(mDate.getTime());
	private Date mEndDate = new Date(GAP_TIME + this.mDate.getTime());

	private TimeZone mTimeZone = TimeZone.getDefault();

	// private String mDateFormatStr = "E, MMM dd";
	private String mDateFormatStr = "yyyy-MM-dd";

	private String mTimeFormatStr = "a hh:mm";

	private EditText mEtTitleName;
	private EditText mEtConfDate;

	private TextView mTvStartTime;
	private TextView mTvEndTime;

	private LinearLayout mLayoutTimeSelector;
	private TextArrow confPeriodArrow;

	private LinearLayout mLayoutRepeatCount;
	private TextArrow mAccessNumberArrow;
	private EditText mEtRepeatCount;

	private SlipControlView mSecurityCode;
	private EditText etMeetingNotes;
	private TextArrow mInvitePartyArrow;

	private TextView mSperatorLine;

	private LinearLayout mSelectedPartLayout;
	private OnClickListener mSecurityCodeListener;
	private OnClickListener mOnSelectedPartyClickListener;
	private DatePickerDialog.OnDateSetListener mDateSetListener;
	private TimePickerDialog.OnTimeSetListener mTimeSetListener;
	private View.OnClickListener mOnDateClick;

	public void onStartTimeClicked(View v) {

		mTimeType = TIME_START;
		OrderConfActivity.this.showDialog(DIALOG_TYPE_TIME);
	}

	public void onEndTimeClicked(View v) {

		mTimeType = TIME_END;
		OrderConfActivity.this.showDialog(DIALOG_TYPE_TIME);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_order_conf);

		mActivity = this;
		
		mAccountId = getIntent()
				.getLongExtra(Constant.KEY_OF_CONF_ACCOUNT_ID, -1);
		initView();
		setShowRightButton(true);
	}

	public void setDate(Date newDate) {

		mDate = newDate;
	}

	public void initView() {

		mInflater = (LayoutInflater) mActivity
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		LinearLayout titleLayout = (LinearLayout) findViewById(R.id.etv_conf_title);
		TextView titleToast = (TextView) titleLayout
				.findViewById(R.id.tv_prompt);
		mEtTitleName = (EditText) titleLayout.findViewById(R.id.et_input);

		titleToast.setText(R.string.toast_order_conf_title);

		// date selector
		LinearLayout timeLayout = (LinearLayout) findViewById(R.id.etv_conf_time);
		TextView timeToast = (TextView) timeLayout.findViewById(R.id.tv_prompt);
		timeToast.setText(R.string.toast_order_conf_date);
		mEtConfDate = (EditText) timeLayout.findViewById(R.id.et_input);

		// time selector
		mLayoutTimeSelector = (LinearLayout) findViewById(R.id.layout_time_selector);
		mTvStartTime = (TextView) mLayoutTimeSelector
				.findViewById(R.id.tv_order_conf_start_time);
		mTvEndTime = (TextView) mLayoutTimeSelector
				.findViewById(R.id.tv_order_conf_end_time);

		// conference period
		confPeriodArrow = (TextArrow) findViewById(R.id.conf_period_arrow);

		// conference repeat count
		mLayoutRepeatCount = (LinearLayout) findViewById(R.id.layout_repeat_count);
		TextView tvCount = (TextView) mLayoutRepeatCount
				.findViewById(R.id.tv_left_toast);
		tvCount.setText(R.string.toast_order_conf_count);
		mEtRepeatCount = (EditText) mLayoutRepeatCount
				.findViewById(R.id.et_content);
		mEtRepeatCount.setInputType(InputType.TYPE_CLASS_NUMBER);

		// dial in number
		mAccessNumberArrow = (TextArrow) findViewById(R.id.access_number_arrow);

		// This set for the edit text can not be editable
		mEtConfDate.setFocusable(false);
		mEtConfDate.setClickable(true);		

		mSecurityCode = (SlipControlView) findViewById(R.id.security_module);
		etMeetingNotes = (EditText) findViewById(R.id.et_meeting_note);
		mInvitePartyArrow = (TextArrow) findViewById(R.id.invite_party_module);
		mSperatorLine = (TextView) findViewById(R.id.sperator_line);
		mSelectedPartLayout = (LinearLayout) findViewById(R.id.layout_selected_parties_module);

		do {

			if (Util.isEmpty(mDate)) {
				break;
			}

			if (!Util.isEmpty(mEtConfDate)) {
				updateDateView();
			}

			if (!Util.isEmpty(mTvStartTime)) {
				updateStartTimeView();
			}

			if (!Util.isEmpty(mTvEndTime)) {
				updateEndTimeView();
			}
		} while (false);

		initListener();
	}

	public void initListener() {

		mOnDateClick = new View.OnClickListener() {
			public void onClick(View paramView) {
				OrderConfActivity.this.showDialog(DIALOG_TYPE_DATE);
			}
		};

		mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {

			@Override
			public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

				GregorianCalendar localGregorianCalendar = new GregorianCalendar();
				localGregorianCalendar
						.setTimeZone(OrderConfActivity.this.mTimeZone);
				localGregorianCalendar.setTime(OrderConfActivity.this.mDate);
				localGregorianCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
				localGregorianCalendar.set(Calendar.MINUTE, minute);
				OrderConfActivity.this
						.setDate(localGregorianCalendar.getTime());

				switch (mTimeType) {

				case TIME_START:

					mStartDate.setTime(mDate.getTime());
					OrderConfActivity.this.updateStartTimeView();
				
					break;

				case TIME_END:
					mEndDate.setTime(mDate.getTime());
					OrderConfActivity.this.updateEndTimeView();
					break;

				default:
					OrderConfActivity.this.updateStartTimeView();
					break;
				}
			}
		};

		mDateSetListener = new DatePickerDialog.OnDateSetListener() {

			@Override
			public void onDateSet(DatePicker view, int year, int monthOfYear,
					int dayOfMonth) {

				GregorianCalendar localGregorianCalendar = new GregorianCalendar();
				localGregorianCalendar.set(Calendar.YEAR, year);
				localGregorianCalendar.set(Calendar.MONTH, monthOfYear);
				localGregorianCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);

				mDate = localGregorianCalendar.getTime();
				
				mStartDate.setYear(mDate.getYear());
				mStartDate.setMonth(mDate.getMonth());
				mStartDate.setDate(mDate.getDate());
				
				mEndDate.setYear(mDate.getYear());
				mEndDate.setMonth(mDate.getMonth());
				mEndDate.setDate(mDate.getDate());
				
				OrderConfActivity.this.updateDateView();
			}
		};

		mOnSelectedPartyClickListener = new OnClickListener() {

			@Override
			public void onClick(View v) {

				// Util.BIZ_CONF_DEBUG(TAG, "onItemClicked called");

				Participant item = (Participant) v.getTag();

				if (!Util.isEmpty(item)) {

					int conatactId = item.getContactId();
					int selectedAttrPos = item
							.getSelectedAttrPosInContactItem();

					ContactManager cm = ContactManager.getInstance();
					cm.removeSelectedContact(item);

					ContactItem contact = cm.getContactById(conatactId);
					contact.setAttrSelectedState(selectedAttrPos, false);

					showSelectedParties();
				}
			}
		};

		mSecurityCodeListener = new OnClickListener() {

			@Override
			public void onClick(View v) {

				do {

					if (Util.isEmpty(mSecurityCode)) {
						break;
					}

					String code = mSecurityCode.getInputContent();

					if (Util.isEmpty(code)) {

						Util.shortToast(mActivity,
								R.string.toast_security_code_null);
						break;
					}

					v.setEnabled(false);

					// security code verify success
					// ...

				} while (false);
			}
		};
		mInvitePartyArrow.setOnArrowClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				
				Intent intent = new Intent();
				intent.setClass(mActivity, AddParticipantActivity.class);
				intent.putExtra(AddParticipantActivity.KEY_OF_SHOW_EMAIL_ADDRESS, true);
				
				mActivity.startActivity(intent);				
			}
		});

		mAccessNumberArrow.setOnArrowClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				Util.startActivityForResult(mActivity,
						AccessNumberActivity.class, REQUEST_CODE_ACCESS_NUMBER);
			}
		});

		mTvStartTime.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				onStartTimeClicked(v);
			}
		});

		mTvEndTime.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				onEndTimeClicked(v);
			}
		});

		confPeriodArrow.setOnArrowClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				Intent intent = new Intent();
				intent.setClass(mActivity, RepeatSelectionActivity.class);
				intent.putExtra(RepeatSelectionActivity.SELECTED_REPEAT_PERIOD,
						mRepeatType);

				mActivity.startActivityForResult(intent,
						REQUEST_CODE_REPEAT_PERIOD);
			}
		});
		
		mEtConfDate.setOnClickListener(mOnDateClick);
		mSecurityCode.setBtClickListener(mSecurityCodeListener);
	}

	@Override
	protected void onResume() {
		super.onResume();

		do {

			if (Util.isEmpty(mLayoutRepeatCount)) {
				break;
			}

			if (mRepeatType != RepeatSelectionActivity.PERIOD_NONE) {

				mLayoutRepeatCount.setVisibility(View.VISIBLE);
				break;
			}

			mLayoutRepeatCount.setVisibility(View.GONE);

		} while (false);

		showSelectedParties();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		// when order meeting finished, clear the selected participants stored
		// in ContactsManager;
		ContactManager.getInstance().clearSelectedParties();
	}

	public void showSelectedParties() {

		// This method give a realization of fixed width layout
		ArrayList<Participant> participants = ContactManager.getInstance()
				.getAllSelectedContacts();

		int partCount = participants.size();

		if (partCount > 0) {

			mSperatorLine.setVisibility(View.VISIBLE);
			mSelectedPartLayout.setVisibility(View.VISIBLE);
		} else {
			mSperatorLine.setVisibility(View.GONE);
			mSelectedPartLayout.setVisibility(View.GONE);
		}
		// remove all views added before
		mSelectedPartLayout.removeAllViews();

		// get the number of layout we should create
		int needInflateViewNum = partCount / Constant.NUM_PER_ROW + 1;

		// when the participant number is 0, 8, 12...we should minus 1,but for 1
		// or 2 or 7..we should not minus 1
		if (partCount % Constant.NUM_PER_ROW == 0) {

			needInflateViewNum = needInflateViewNum - 1;
		}

		// add the layout view we should show later
		for (int i = 0; i < needInflateViewNum; i++) {

			mSelectedPartLayout.addView(getParticipantListView());
		}

		// the row corresponding to the layout view and participant
		int row = 0;

		int pos = 0;

		for (int i = 0; i < partCount; i++, pos++) {

			Participant participant = participants.get(i);

			String showText = participant.getName();

			if (Util.isEmpty(showText)) {

				showText = participant.getPhone();
			}

			if (Util.isEmpty(showText)) {

				showText = participant.getEmail();
			}

			// get the row number of the participant
			row = pos / Constant.NUM_PER_ROW;

			// get the column index of the participant should show in the row
			int index = pos - Constant.NUM_PER_ROW * row;

			// if the show text too long, this participant should occupy one row
			if (StringUtil.getStrLengthInChar(showText) 
							> Constant.MAX_LENGTH_OF_SHOW_TEXT) {

				mSelectedPartLayout.addView(getParticipantListView());
				pos = pos + Constant.NUM_PER_ROW - 1;

				if (index > 0) {
					// when change row, the pos should add too
					row++;
					pos++;
				}
			}
			Util.BIZ_CONF_DEBUG(TAG, "showText.length(): " + showText.length());
			Util.BIZ_CONF_DEBUG(TAG, "pos: " + pos + " index: " + index
					+ " row: " + row);

			LinearLayout item = (LinearLayout) mSelectedPartLayout
					.getChildAt(row);

			// show the specified participant
			TextView tvName = (TextView) item.getChildAt(index);
			tvName.setText(showText);
			tvName.setVisibility(View.VISIBLE);
			tvName.setOnClickListener(mOnSelectedPartyClickListener);

			// set the participant as tag of the text view, we will use it when
			// user click the textview
			tvName.setTag(participant);
		}
	}

	public LinearLayout getParticipantListView() {

		LinearLayout view = (LinearLayout) mInflater.inflate(
				R.layout.item_participant_list, null);

		return view;
	}

	@Override
	public void onRightButtonClicked(View v) {
		
		do {
			
			String title = mEtTitleName.getText().toString();
			
			if (Util.isEmpty(title)) {
				
				Util.requestFocus(mEtTitleName);
				break;
			}
			
			String accessNumber = mAccessNumberArrow.getCenterConentText();
			
			if(Util.isEmpty(accessNumber)) {
				
				Util.requestFocus(mAccessNumberArrow);
				break;
			}
			
			String notes = etMeetingNotes.getText().toString();
			
			if (Util.isEmpty(notes)) {
				
				Util.requestFocus(etMeetingNotes);
				break;
			}
			
			MeetingDBAdapter meetingDb = 
					new MeetingDBAdapter(MeetingDbTable.MEETING_DB_TABLE, MeetingDbTable.getAllColumns());
			
			meetingDb.open();
			
			Meeting meeting = new Meeting();
			
			meeting.setAccountId(String.valueOf(mAccountId));
			meeting.setTitle(title);
			
			
			SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat(
					mDateFormatStr);
			localSimpleDateFormat.setTimeZone(mTimeZone);
			String str = localSimpleDateFormat.format(mStartDate);
			
			Util.BIZ_CONF_DEBUG(TAG, "start date str: " + str);
			
			
			meeting.setStartTime(mStartDate.getTime());		
			meeting.setEndTime(mEndDate.getTime());
			meeting.setAccessNumber(accessNumber);
			meeting.setSecurityCode(mSecurityCode.getInputContent());
			meeting.setNote(notes);
			meeting.setDate(mEtConfDate.getText().toString());
			
			//should add invites here
			////
			///
			
			CalendarUtil.insertEvent(meeting);
			
			meetingDb.insertObject(meeting);
			
			MeetingManager.getInstance().addMeeting(meeting);
			
			Util.BIZ_CONF_DEBUG(TAG, "date description: " + meeting.getDate());
			meetingDb.close();		
			finish();
		}while(false);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		switch (requestCode) {

		case REQUEST_CODE_ACCESS_NUMBER:

			if (resultCode == RESULT_OK) {

				String accessNumber = data.getExtras().getString(
						AccessNumberActivity.KEY_ACCESS_NUMBER);

				if (Util.isEmpty(accessNumber)) {

					mAccessNumberArrow.setCenterContentText(this.getResources()
							.getString(R.string.none));
				} else {

					mAccessNumberArrow.setCenterContentText(accessNumber);
				}
			}
			break;

		case REQUEST_CODE_REPEAT_PERIOD:

			do {

				if (resultCode != RESULT_OK) {
					break;
				}

				if (Util.isEmpty(confPeriodArrow)) {
					break;
				}

				mRepeatType = data.getIntExtra(
						RepeatSelectionActivity.SELECTED_REPEAT_PERIOD,
						RepeatSelectionActivity.PERIOD_NONE);

				confPeriodArrow.setCenterContentText(RepeatSelectionActivity
						.getPeriodString(mRepeatType));

			} while (false);

			break;
		default:
			break;
		}

		super.onActivityResult(requestCode, resultCode, data);
	}

	@Override
	public void setTitleName(String title) {
		super.setTitleName(title);
	}

	@Override
	@Deprecated
	protected Dialog onCreateDialog(int id) {
		GregorianCalendar localGregorianCalendar = new GregorianCalendar();
		localGregorianCalendar.setTime(this.mDate);
		localGregorianCalendar.setTimeZone(this.mTimeZone);
		switch (id) {
		default:
			return null;
		case DIALOG_TYPE_DATE:

			return new DatePickerDialog(this, this.mDateSetListener,
					localGregorianCalendar.get(Calendar.YEAR),
					localGregorianCalendar.get(Calendar.MONTH),
					localGregorianCalendar.get(Calendar.DAY_OF_MONTH));

		case DIALOG_TYPE_TIME:
			int day = localGregorianCalendar.get(Calendar.HOUR_OF_DAY);
			int minute = localGregorianCalendar.get(Calendar.MINUTE);

			return new TimePickerDialog(this, this.mTimeSetListener, day,
					minute, false);
		}
	}

	@Override
	@Deprecated
	protected void onPrepareDialog(int paramInt, Dialog paramDialog, Bundle args) {
		
		GregorianCalendar localGregorianCalendar = new GregorianCalendar();
		localGregorianCalendar.setTime(this.mDate);
		localGregorianCalendar.setTimeZone(this.mTimeZone);
		
		switch (paramInt) {
		
		default:
			return;
		case DIALOG_TYPE_DATE:
			((DatePickerDialog) paramDialog).updateDate(
					localGregorianCalendar.get(Calendar.YEAR),
					localGregorianCalendar.get(Calendar.MONTH),
					localGregorianCalendar.get(Calendar.DAY_OF_MONTH));
			return;
			
		case DIALOG_TYPE_TIME:
			int hour = localGregorianCalendar.get(Calendar.HOUR_OF_DAY);
			int minute = localGregorianCalendar.get(Calendar.MINUTE);
			((TimePickerDialog) paramDialog).updateTime(hour, minute);
			return;
		}
	}

	private void updateDateView() {
		SimpleDateFormat localSimpleDateFormat = new SimpleDateFormat(
				this.mDateFormatStr);
		localSimpleDateFormat.setTimeZone(this.mTimeZone);
		String str = localSimpleDateFormat.format(this.mDate);
		this.mEtConfDate.setText(str);
		
		Util.BIZ_CONF_DEBUG(TAG, "date str: " + str);
	}

	private void updateStartTimeView() {

		String str = DateUtil.getFormatString(mStartDate, DateUtil.A_HH_MM);
		this.mTvStartTime.setText(str);
	}

	private void updateEndTimeView() {
		
		String str = DateUtil.getFormatString(mEndDate, DateUtil.A_HH_MM);
		this.mTvEndTime.setText(str);
	}
}
